﻿namespace Voxel2Unity
{
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Text;
    using UnityEngine;

    public static class QbFile
    {
        public static byte[] GetQbByte(QbData _data)
        {
            List<byte> list = new List<byte>();
            list.AddRange(BitConverter.GetBytes(_data.Version));
            list.AddRange(BitConverter.GetBytes(_data.ColorFormat));
            list.AddRange(BitConverter.GetBytes(_data.ZAxisOrientation));
            list.AddRange(BitConverter.GetBytes(0));
            list.AddRange(BitConverter.GetBytes(_data.VisibleMask));
            list.AddRange(BitConverter.GetBytes(_data.NumMatrixes));
            uint zAxisOrientation = _data.ZAxisOrientation;
            if ((zAxisOrientation == 0) || (zAxisOrientation != 1))
            {
                _data.Flip(Voxel2Unity.Axis.X);
                _data.Rotate(Voxel2Unity.Axis.X, false);
                _data.Flip(Voxel2Unity.Axis.Y);
            }
            else
            {
                _data.Flip(Voxel2Unity.Axis.X);
                _data.Rotate(Voxel2Unity.Axis.X, true);
            }
            for (int i = 0; i < _data.NumMatrixes; i++)
            {
                int num3;
                int num4;
                QbData.QbMatrix matrix9;
                QbData.QbMatrix matrix10;
                QbData.QbMatrix matrix11;
                QbData.QbMatrix matrix12;
                QbData.QbMatrix matrix = _data.MatrixList[i];
                list.Add(matrix.NameLength);
                QbData.QbMatrix matrix2 = _data.MatrixList[i];
                list.AddRange(Encoding.Default.GetBytes(matrix2.Name));
                QbData.QbMatrix matrix3 = _data.MatrixList[i];
                list.AddRange(BitConverter.GetBytes(matrix3.SizeX));
                QbData.QbMatrix matrix4 = _data.MatrixList[i];
                list.AddRange(BitConverter.GetBytes(matrix4.SizeY));
                QbData.QbMatrix matrix5 = _data.MatrixList[i];
                list.AddRange(BitConverter.GetBytes(matrix5.SizeZ));
                QbData.QbMatrix matrix6 = _data.MatrixList[i];
                list.AddRange(BitConverter.GetBytes(matrix6.PosX));
                QbData.QbMatrix matrix7 = _data.MatrixList[i];
                list.AddRange(BitConverter.GetBytes(matrix7.PosY));
                QbData.QbMatrix matrix8 = _data.MatrixList[i];
                list.AddRange(BitConverter.GetBytes(matrix8.PosZ));
                int num2 = 0;
                goto Label_023E;
            Label_01C1:
                num3 = 0;
                goto Label_021F;
            Label_01C8:
                num4 = 0;
                goto Label_01FF;
            Label_01D0:
                matrix9 = _data.MatrixList[i];
                list.AddRange(BitConverter.GetBytes(matrix9.Voxels[num4, num3, num2]));
                num4++;
            Label_01FF:
                matrix10 = _data.MatrixList[i];
                if (num4 < matrix10.SizeX)
                {
                    goto Label_01D0;
                }
                num3++;
            Label_021F:
                matrix11 = _data.MatrixList[i];
                if (num3 < matrix11.SizeY)
                {
                    goto Label_01C8;
                }
                num2++;
            Label_023E:
                matrix12 = _data.MatrixList[i];
                if (num2 < matrix12.SizeZ)
                {
                    goto Label_01C1;
                }
            }
            return list.ToArray();
        }

        public static QbData LoadQb(string path)
        {
            return LoadQb(Util.FileToByte(path));
        }

        public static QbData LoadQb(byte[] _data)
        {
            using (MemoryStream stream = new MemoryStream(_data))
            {
                using (BinaryReader reader = new BinaryReader(stream))
                {
                    QbData data = new QbData {
                        Version = reader.ReadUInt32(),
                        ColorFormat = reader.ReadUInt32(),
                        ZAxisOrientation = reader.ReadUInt32(),
                        Compressed = reader.ReadUInt32()
                    };
                    reader.ReadUInt32();
                    data.NumMatrixes = reader.ReadUInt32();
                    data.MatrixList = new List<QbData.QbMatrix>();
                    for (int i = 0; i < data.NumMatrixes; i++)
                    {
                        int num8;
                        int num9;
                        int num10;
                        QbData.QbMatrix item = new QbData.QbMatrix();
                        int count = reader.ReadByte();
                        item.Name = reader.ReadChars(count).ToString();
                        item.SizeX = reader.ReadInt32();
                        item.SizeY = reader.ReadInt32();
                        item.SizeZ = reader.ReadInt32();
                        item.PosX = reader.ReadInt32();
                        item.PosY = reader.ReadInt32();
                        item.PosZ = reader.ReadInt32();
                        item.Voxels = new int[item.SizeX, item.SizeY, item.SizeZ];
                        if (data.Compressed == 0)
                        {
                            num10 = 0;
                            while (num10 < item.SizeZ)
                            {
                                num9 = 0;
                                while (num9 < item.SizeY)
                                {
                                    num8 = 0;
                                    while (num8 < item.SizeX)
                                    {
                                        item.Voxels[num8, num9, num10] = (int) reader.ReadUInt32();
                                        num8++;
                                    }
                                    num9++;
                                }
                                num10++;
                            }
                        }
                        else
                        {
                            for (num10 = 0; num10 < item.SizeZ; num10++)
                            {
                                int num2;
                                int num = 0;
                            Label_0183:
                                num2 = (int) reader.ReadUInt32();
                                switch (num2)
                                {
                                    case 6L:
                                        break;

                                    case 2L:
                                    {
                                        uint num3 = reader.ReadUInt32();
                                        num2 = (int) reader.ReadUInt32();
                                        for (int m = 0; m < num3; m++)
                                        {
                                            num8 = num % item.SizeX;
                                            num9 = num / item.SizeX;
                                            num++;
                                            item.Voxels[num8, num9, num10] = num2;
                                        }
                                        goto Label_0183;
                                    }
                                    default:
                                        num8 = num % item.SizeX;
                                        num9 = num / item.SizeX;
                                        num++;
                                        item.Voxels[num8, num9, num10] = num2;
                                        goto Label_0183;
                                }
                            }
                        }
                        data.MatrixList.Add(item);
                    }
                    Vector3 zero = Vector3.zero;
                    for (int j = 0; j < data.NumMatrixes; j++)
                    {
                        QbData.QbMatrix matrix2 = data.MatrixList[j];
                        if (j == 0)
                        {
                            zero = new Vector3((float) matrix2.PosX, (float) matrix2.PosY, (float) matrix2.PosZ);
                        }
                        else
                        {
                            float x = Mathf.Min((float) matrix2.PosX, zero.x);
                            float y = Mathf.Min((float) matrix2.PosY, zero.y);
                            zero = new Vector3(x, y, Mathf.Min((float) matrix2.PosZ, zero.z));
                        }
                    }
                    for (int k = 0; k < data.NumMatrixes; k++)
                    {
                        QbData.QbMatrix matrix3 = data.MatrixList[k];
                        matrix3.PosX -= (int) zero.x;
                        matrix3.PosY -= (int) zero.y;
                        matrix3.PosZ -= (int) zero.z;
                        data.MatrixList[k] = matrix3;
                    }
                    uint zAxisOrientation = data.ZAxisOrientation;
                    if ((zAxisOrientation == 0) || (zAxisOrientation != 1))
                    {
                        data.Flip(Voxel2Unity.Axis.X);
                        data.Rotate(Voxel2Unity.Axis.X, false);
                        data.Flip(Voxel2Unity.Axis.Y);
                        return data;
                    }
                    data.Flip(Voxel2Unity.Axis.X);
                    data.Rotate(Voxel2Unity.Axis.X, false);
                    return data;
                }
            }
        }
    }
}

